﻿using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Routing;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TransformerManager.Shared.Dto.OperationLog;
using TransformerManager.Shared.Helper;
using TransformerManager.Shared.Helper.HttpParams;
using TransformerManager.Shared.Servers;

namespace TransformerManager.API.Controllers
{
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiController]
    [Authorize]
    public class OperationLogController : Controller
    {
        private readonly IOperationLogService _operationLogService;
        private readonly IUrlHelper _urlHelper;
        private readonly IMapper _mapper;

        public OperationLogController(
            IMapper mapper, 
            IOperationLogService operationLogServic, 
            IActionContextAccessor actionContextAccessor, 
            IUrlHelperFactory urlHelperFactory)
        {
            _operationLogService = operationLogServic;
            _urlHelper = urlHelperFactory.GetUrlHelper(actionContextAccessor.ActionContext);
            _mapper = mapper;
        }

        /// <summary>
        /// 为Get请求返回的头部数据生成前一页和后一页的URL
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="operateTimeStart"></param>
        /// <param name="operateTimeEnd"></param>
        /// <param name="paginationParams"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private string GenerateOperationLogsResourceURL(
            string userName,
            DateTime operateTimeStart,
            DateTime operateTimeEnd,
            PaginationResourceParameters paginationParams,
            ResourceUrlType type)
        {
            return type switch
            {
                ResourceUrlType.PreviousPage => _urlHelper.Link("GetOperationLogs",
                        new
                        {
                            userName = userName,
                            operateTimeStart = operateTimeStart,
                            operateTimeEnd = operateTimeEnd,
                            pageNumber = paginationParams.PageNumber - 1,
                            pageSize = paginationParams.PageSize
                        }),
                ResourceUrlType.NextPage => _urlHelper.Link("GetOperationLogs",
                        new
                        {
                            userName = userName,
                            operateTimeStart = operateTimeStart,
                            operateTimeEnd = operateTimeEnd,
                            pageNumber = paginationParams.PageNumber + 1,
                            pageSize = paginationParams.PageSize
                        }),
                _ => throw new NotImplementedException()
            };
        }

        [Authorize(AuthenticationSchemes = "Bearer")]
        [Authorize(Roles = "SuperAdmin, Admin")]
        [HttpGet("Query", Name = "GetOperationLogs")]
        [HttpHead]
        public async Task<ActionResult<ServiceResponse<IEnumerable<OperationLogsDto>>>> GetOperationLogs(
            [FromQuery] string userName,
            [FromQuery] DateTime operateTimeStart,
            [FromQuery] DateTime operateTimeEnd,
            [FromQuery] PaginationResourceParameters paginationParams)
        {
            var response = new ServiceResponse<IEnumerable<OperationLogsDto>>();

            var optLogFromRepo = await _operationLogService.GetOperationLogsAsync(
                userName,
                operateTimeStart,
                operateTimeEnd,
                paginationParams);

            var optLogDto = _mapper.Map<IEnumerable<OperationLogsDto>>(optLogFromRepo);

            // 生成前一页的URL
            var previousPageLink = optLogFromRepo.HasPrevious ?
                GenerateOperationLogsResourceURL(userName, operateTimeStart, operateTimeEnd, paginationParams, ResourceUrlType.PreviousPage) : null;

            // 生成后一页的URL
            var nextPageLink = optLogFromRepo.HasNext ?
                GenerateOperationLogsResourceURL(userName, operateTimeStart, operateTimeEnd, paginationParams, ResourceUrlType.NextPage) : null;

            var paginationMetadata = new
            {
                previousPageLink,
                nextPageLink,
                totalCount = optLogFromRepo.TotalCount,
                pageSize = optLogFromRepo.PageSize,
                currentPage = optLogFromRepo.CurrentPage,
                totalPages = optLogFromRepo.TotalPages
            };

            // 通过Response的头部信息返回hatos成熟度3等级的restful头信息
            Response.Headers.Add("x-pagination",
                Newtonsoft.Json.JsonConvert.SerializeObject(paginationMetadata));

            response.Data = optLogDto;
            return Ok(response);
        }

        [Authorize(AuthenticationSchemes = "Bearer")]
        [Authorize(Roles = "SuperAdmin, Admin")]
        [HttpGet("RequestBody/{id}")]
        public async Task<ActionResult<ServiceResponse<string>>> GetRequestBodyById([FromRoute] int id)
        {
            var response = new ServiceResponse<string>();

            var optLogFromRepo = await _operationLogService.GetOperationLogByIdAsync(id);

            if (optLogFromRepo == null)
            {
                response.Success = false;
                response.Message = $"未检索到id={id}的操作日志!";
                return NotFound(response);
            }

            var result = string.IsNullOrEmpty(optLogFromRepo.RequestBody) ? "{}" : optLogFromRepo.RequestBody;

            response.Data = result;
            return Ok(response);
        }
    }
}
